/*
# MIAHX© 交互框架信息表示模型的 FastDDS 参与者的 C++ 实现

**模块：MIAHX© / 框架基础服务层（FFST） / 交互框架信息表示模型（IFIRM）**

Version: 0.4.10
Last updated: October 16, 2024

## Contributor(s)
* YAO Naiming <[naiming@iscas.ac.cn](mailto:naiming@iscas.ac.cn)>

## Change log
### v0.4.10
- .16: [更新] 新增注释，调整 include 逻辑
- .15: [更新] 版本同步至 Python 版v0.4.10.14
### v0.4.7
- .26: [新增] 初始实现

---
Copyright © 2024-2025 MIAHX Contributors, ISCAS, and ASIC. All Rights Reserved.
Licensed under Apache-2.0.
*/

#include "../include/miahx/participant.h"


Participant::Participant(Domains domain,
                         ParticipantQosTypes qos_type) {
    if (domain > 200) {
        return;
    }

    this->domain = domain;

    auto factory = DomainParticipantFactory::get_instance();
    DomainParticipantQos pqos;
    if (qos_type == ParticipantQosTypes::PARTICIPANT_QOS_TYPES_LARGE_DATA) {
        // TODO:
    } else {
        factory->get_default_participant_qos(pqos);
        this->_participant = factory->create_participant((DomainId_t) domain, pqos);
    }
}

Participant::~Participant() {
    this->_participant->delete_contained_entities();
    DomainParticipantFactory::get_instance()->delete_participant(this->_participant);
}

Topic *Participant::add_topic(const std::string &topic_name, TopicDataType *topic_data_type) {
    if (topic_name.empty()) {
        return nullptr;
    }
    if (topic_data_type == nullptr) {
        return nullptr;
    }
    Topic *topic;
    this->_lock.lock();
    auto pos = this->_topics.find(topic_name);
    if (pos != this->_topics.end()) {
        topic = pos->second.topic;
    } else {
        TypeSupport type_support(topic_data_type);
        type_support.register_type(this->_participant);
        topic = this->_participant->create_topic(topic_name, topic_data_type->getName(), TOPIC_QOS_DEFAULT);
        topic_description desc;
        desc.topic_data_type = topic_data_type;
        desc.topic = topic;
        this->_topics[topic_name] = desc;
    }
    this->_lock.unlock();
    return topic;
}

Publisher *Participant::add_publisher(PublisherQosTypes qos_type) {
    Publisher *publisher;
    this->_lock.lock();
    auto pos = this->_pubs.find(qos_type);
    if (pos != this->_pubs.end()) {
        publisher = pos->second;
    } else {
        switch (qos_type) {
            default:
                publisher = this->_participant->create_publisher(PUBLISHER_QOS_DEFAULT, nullptr);
                break;
        }
        assert(publisher != nullptr);
        this->_pubs[qos_type] = publisher;
    }
    this->_lock.unlock();
    return publisher;
}

Subscriber *Participant::add_subscriber(SubscriberQosTypes qos_type) {
    Subscriber *subscriber;
    this->_lock.lock();
    auto pos = this->_subs.find(qos_type);
    if (pos != this->_subs.end()) {
        subscriber = pos->second;
    } else {
        switch (qos_type) {
            default:
                subscriber = this->_participant->create_subscriber(SUBSCRIBER_QOS_DEFAULT, nullptr);
                break;
        }
        assert(subscriber != nullptr);
        this->_subs[qos_type] = subscriber;
    }
    this->_lock.unlock();
    return subscriber;
}
